package myky.com.doctorapp.api;


import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.ObservableTransformer;
import io.reactivex.functions.Function;
import myky.com.doctorapp.api.Exception.ApiException;
import myky.com.doctorapp.api.Exception.CustomException;
import myky.com.doctorapp.base.BaseEntity;
import myky.com.doctorapp.entity.PageEntity;

/**
 * Created by Zaifeng on 2018/2/28.
 * 对返回的数据进行处理，区分异常的情况。
 */

public class ResponseTransformer {

    public static <T> ObservableTransformer<BaseEntity<T>, T> handleResult() {
        return upstream -> upstream
                .onErrorResumeNext(new ErrorResumeFunction<>())
                .flatMap(new ResponseFunction<>());
    }


    /**
     * 非服务器产生的异常，比如本地无无网络请求，Json数据解析错误等等。
     *
     * @param <T>
     */
    private static class ErrorResumeFunction<T> implements Function<Throwable, ObservableSource<? extends BaseEntity<T>>> {

        @Override
        public ObservableSource<? extends BaseEntity<T>> apply(Throwable throwable) {
            return Observable.error(CustomException.handleException(throwable));
        }
    }

    /**
     * 服务其返回的数据解析
     * 正常服务器返回数据和服务器可能返回的exception
     *
     * @param <T>
     */
    private static class ResponseFunction<T> implements Function<BaseEntity<T>, ObservableSource<T>> {

        @Override
        public ObservableSource<T> apply(BaseEntity<T> tResponse) {
            String message = tResponse.getMsg();
            T data = null;
            Integer resultCode = -1;
            if (tResponse.type != null) {
                resultCode = tResponse.type;
            } else if (tResponse.code != null) {
                resultCode = tResponse.code;
            }
            if (tResponse.payLoad != null) {
                data = tResponse.payLoad;
            } else if (tResponse.data != null) {
                data = tResponse.data;
            }
            PageEntity pageEntity = new PageEntity();
            pageEntity.setCurrent(tResponse.getCurrent());
            pageEntity.setTotal(tResponse.getTotal());
            pageEntity.setSize(tResponse.getSize());
            pageEntity.setPages(tResponse.getPages());
            pageEntity.setVersion(tResponse.getVersion());
            tResponse.setPageEntity(pageEntity);
            if (data != null) {
                return Observable.just(data);
            } else {
                return Observable.error(new ApiException(resultCode, message));
            }
        }
    }


}
